/**********************************************************************
 *@Project： clouddemo
 *@File: ShiroAutoConfiguration
 *@Date: 2017/4/18
 *@Copyright (C) 2013-2017 http://www.posun.cn. All Rights Reserved.
 ***********************************************************************
 *注意： 本内容仅限于深圳市普盛实业有限公司内部使用，禁止外泄
 **********************************************************************
 */
package com.posun.edu.system.config;

import com.google.common.collect.Lists;
import com.posun.framework.cache.RedisManager;
import com.posun.framework.cache.helper.RedissonHelper;
import com.posun.framework.security.cache.RedisShiroCacheManager;
import com.posun.framework.security.session.mgt.AresSessionFactory;
import com.posun.framework.security.session.mgt.AresSessionManager;
import com.posun.framework.security.session.mgt.eis.AresSessionDAO;
import com.posun.framework.security.session.mgt.schedule.AresSessionValidationScheduler;
import org.apache.shiro.session.SessionListener;
import org.apache.shiro.session.mgt.SessionFactory;
import org.apache.shiro.session.mgt.SessionValidationScheduler;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;

import java.util.Collection;

/**
 * <p>
 * TODO<br>
 *
 * @author YL
 * @version 1.0
 * @createTime 2017/4/18 12:33
 * @ChangeLog
 */
@Configuration
@ConditionalOnWebApplication
@ConditionalOnProperty(prefix = "shiro", value = "cookieDomain")
@EnableConfigurationProperties(ShiroProperties.class)
public class ShiroAutoConfiguration {

    @Autowired
    public TaskScheduler taskScheduler;

/*    @Bean
    public FilterRegistrationBean filterRegistrationBean() {
        FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
        filterRegistration.setFilter(new DelegatingFilterProxy("shiroFilter"));
        // 该值缺省为false,表示生命周期由SpringApplicationContext管理,
        //设置为true则表示由ServletContainer管理
        filterRegistration.addInitParameter("targetFilterLifecycle", "true");
        filterRegistration.setEnabled(true);
        filterRegistration.addUrlPatterns("*//*");
        return filterRegistration;
    }*/

    @Bean()
    public RedisManager redisManager() {
        return new RedissonHelper();
    }

    @Bean
    public RedisShiroCacheManager cacheManager(RedisManager redisManager, ShiroProperties shiroProperties) {
        RedisShiroCacheManager redisShiroCacheManager = new RedisShiroCacheManager();
        redisShiroCacheManager.setKeyPrefix(shiroProperties.getCacheKeyPrefix());
        redisShiroCacheManager.setRedisManager(redisManager);
        return redisShiroCacheManager;
    }

    @Bean
    public AresSessionFactory sessionFactory() {
        return new AresSessionFactory();
    }

    @Bean
    public AresSessionDAO sessionDAO(RedisManager redisManager) {
        AresSessionDAO aresSessionDAO = new AresSessionDAO();
        aresSessionDAO.setRedisManager(redisManager);
        return aresSessionDAO;
    }

    @Bean
    public AresSessionValidationScheduler sessionValidationScheduler(ShiroProperties shiroProperties) {
        AresSessionValidationScheduler sessionValidationScheduler = new AresSessionValidationScheduler();
        sessionValidationScheduler.setScheduler(taskScheduler);
        sessionValidationScheduler.setSessionValidationInterval(shiroProperties.getValidationInterval());
        return sessionValidationScheduler;
    }

    @Bean
    @ConditionalOnMissingBean(SimpleCookie.class)
    public SimpleCookie simpleCookie(ShiroProperties shiroProperties) {
        SimpleCookie simpleCookie = new SimpleCookie(shiroProperties.getCookieName());
        simpleCookie.setPath(shiroProperties.getCookiePath());
        simpleCookie.setDomain(shiroProperties.getCookieDomain());
        return simpleCookie;
    }

    @Bean
    public AresSessionManager sessionManager(SessionFactory sessionFactory, SessionDAO sessionDAO,
                                             SimpleCookie simpleCookie, ShiroProperties shiroProperties,
                                             SessionValidationScheduler sessionValidationScheduler) {
        AresSessionManager sessionManager = new AresSessionManager();
        sessionManager.setGlobalSessionTimeout(shiroProperties.getGlobalSessionTimeout());
        sessionManager.setSessionDAO(sessionDAO);
        sessionManager.setSessionFactory(sessionFactory);
        sessionManager.setSessionIdUrlRewritingEnabled(false);

        sessionManager.setSessionValidationSchedulerEnabled(true);
        sessionManager.setSessionValidationScheduler(sessionValidationScheduler);
        sessionManager.setDeleteInvalidSessions(true);

        sessionManager.setSessionIdCookieEnabled(true);
        sessionManager.setSessionIdCookie(simpleCookie);

        Collection<SessionListener> listeners = Lists.newArrayList();
        listeners.add(new AresSessionListener());
        sessionManager.setSessionListeners(listeners);
        return sessionManager;
    }

    /**
     * 开启shiro动态代理
     *
     * @return
     */
    @Bean
    @ConditionalOnMissingBean
    public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator daap = new DefaultAdvisorAutoProxyCreator();
        daap.setProxyTargetClass(true);
        return daap;
    }

    @Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

}
